<?php

namespace summermvc;

use EventBase;
use EventHttp;
use EventBuffer;
use EventHttpRequest;

define('PID', getmypid());
define('ENTRYPOINT_MS', round(microtime(true) * 1000));
defined('ENTRY_ROOT') or define('ENTRY_ROOT', __DIR__);

class SummerMvcApplication
{
    private static $instance = null;

    /**
     * constroctor
     */
    private function __construct()
    {}

    /**
     * @return SummerMvcApplication
     */
    private static function getInstance()
    {
        if (self::$instance) return self::$instance;
        return self::$instance = new self();
    }

    /**
     * color text
     */
    private function colorText($text, $color = null)
    {
        return [
            'red' => "\033[0;31m".$text."\033[0m",
            'green' => "\033[0;32m".$text."\033[0m",
            'yellow' => "\033[0;33m".$text."\033[0m",
            'blue' => "\033[0;34m".$text."\033[0m",
            'magenta' => "\033[0;35m".$text."\033[0m",
            'cyan' => "\033[0;36m".$text."\033[0m",
            'white' => "\033[0;37m".$text."\033[0m",
        ][$color] ?? $text;
    }

    /**
     * parse class name
     */
    private function parserClassName(string $className)
    {
        if (strlen($className) > 20) {
            $group = explode('\\', $className);
            $baseClassName = array_pop($group);
            return implode('.', array_merge(array_map(function($v) {
                return substr($v, 0, 1);
            }, $group), [$baseClassName]));
        } 
        return str_replace('\\', '.', $className);
    }

    /**
     * parse class basename
     */
    private function parserClassBasename(string $className)
    {
        $group = explode("\\", $className);
        return array_pop($group);
    }

    /**
     * @param string $application
     * @param array $args
     */
    public static function run(string $application, array $args = [])
    {
        $composer = file_get_contents(dirname(__DIR__) . '/composer.json');
        $composerDependency = json_decode($composer);

echo <<<DOC

//|_____                                   ____  
|/|/ ___/__  ______ ___  ____ ___  ___  ____\ \ \ 
   \__ \/ / / / __ `__ \/ __ `__ \/ _ \/ ___/\ \ \
  ___/ / /_/ / / / / / / / / / / /  __/ /    / / /
 /____/\__,_/_/ /_/ /_/_/ /_/ /_/\___/_/    /_/_/ 
DOC;
        echo PHP_EOL . PHP_EOL;
        echo self::getInstance()->colorText(':: Summer Mvc ::', 'green') . str_pad("(v{$composerDependency->version})", 32, " ", STR_PAD_LEFT);
        echo PHP_EOL . PHP_EOL;

        echo date_format(date_create(), 'Y-m-d\TH:i:s.vP') . "  " . self::getInstance()->colorText('INFO', 'green'). " ". self::getInstance()->colorText(PID, 'magenta') . " --- [" . str_pad("main", 15, " ", STR_PAD_LEFT) . "] ". 
            str_pad(self::getInstance()->parserClassName($application), 40, " ", STR_PAD_RIGHT) ." : " . 
            "Starting ".self::getInstance()->parserClassBasename($application)." using PHP ". PHP_VERSION ." with PID ". PID ." (". ENTRY_ROOT ." started by " . get_current_user() . " )" . "\n";

        echo date_format(date_create(), 'Y-m-d\TH:i:s.vP') . "  " . self::getInstance()->colorText('INFO', 'green'). " ". self::getInstance()->colorText(PID, 'magenta') . " --- [" . str_pad("main", 15, " ", STR_PAD_LEFT) . "] ". 
            str_pad(self::getInstance()->parserClassName($application), 40, " ", STR_PAD_RIGHT) ." : " . 
            "EventHTTP initialized with port(s): 8081 (http)" . "\n";

        echo date_format(date_create(), 'Y-m-d\TH:i:s.vP') . "  " . self::getInstance()->colorText('INFO', 'green'). " ". self::getInstance()->colorText(PID, 'magenta') . " --- [" . str_pad("main", 15, " ", STR_PAD_LEFT) . "] ". 
            str_pad(self::getInstance()->parserClassName($application), 40, " ", STR_PAD_RIGHT) ." : " . 
            "Root WebApplicationContext: initialization completed in ". (round(microtime(true) * 1000) - ENTRYPOINT_MS) ." ms" . "\n";
        /* $base = new EventBase();
        $server = new EventHttp($base);
        $server->setCallback("/", function(EventHttpRequest $req) {
            
            $buffer = new EventBuffer();
            $buffer->add("hello");
            
            $req->sendReply(200 ,'OK', $buffer);
        });
        $server->bind("127.0.0.1", 9600);
        $base->dispatch(); */

    }
}